package com.personal.ifanya.infrastructure.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public class Log {

	
	private static final Logger log = LoggerFactory.getLogger(Log.class);
 
	/**
	 * Generally speaking, for service it's service; for application it's application.
	 */
	private static String appAlias = "Application"; 
	
	/** uniformed log error method 
	 * @param callerClass  caller's class name
	 * @param apiFunctionName  name of interface's api-function
	 * @param exception the exception needed to be logged.
	 * @see uniformed log warn method: {@link #logWarn(Class, String, Exception)}
	 */
	public static void logError(Class callerClass, String apiFunctionName, Exception exception)
	{
		log.error(getLogString(callerClass,apiFunctionName,"",exception));
	}
	

	/** uniformed log error method 
	 * @param callerClass  caller's class name
	 * @param apiFunctionName name of interface's api-function
	 * @param userDefinedBizMsg  user defined message for business use. 
	 * @param exception the exception needed to be logged.
	 * @see  uniformed log warn method: {@link #logWarn(Class, String, String, Exception)}
	 */
	public static void logError(Class callerClass, String apiFunctionName, String userDefinedBizMsg, Exception exception)
	{
		log.error(getLogString(callerClass,apiFunctionName,userDefinedBizMsg,exception));
	}
    
	
	
	/** uniformed log warn method 
	 * @param callerClass  caller's class name
	 * @param apiFunctionName  name of interface's api-function
	 * @param exception the exception needed to be logged.
	 * @see uniformed log error method: {@link #logError(Class, String, Exception)}
	 */
	public static void logWarn(Class callerClass, String apiFunctionName, Exception exception)
	{
		log.warn(getLogString(callerClass,apiFunctionName,"",exception));
	}
	
	
	/** uniformed log warn method 
	 * @param callerClass caller's class name
	 * @param apiFunctionName name of interface's api-function
	 * @param userDefinedBizMsg  user defined message for business use.
	 * @param exception the exception needed to be logged.
	 * @see uniformed log error method: {@link #logError(Class, String, String, Exception)}
	 */
	public static void logWarn(Class callerClass, String apiFunctionName, String userDefinedBizMsg, Exception exception)
	{
		log.warn(getLogString(callerClass,apiFunctionName,userDefinedBizMsg,exception));
	}
	
	private static String getLogString(Class callerClass, String apiFunctionName, String userDefinedBizMsg, Exception exception)
	{
		return  String.format("[Log] %s name: %s, interfaceAPI name:%s(), biz message: %s, exception message:%s, stack trace: %s", 
								appAlias,
								callerClass.getName()==null? "":callerClass.getName() , 
								userDefinedBizMsg==null? "":userDefinedBizMsg, 
								apiFunctionName ==null?"":apiFunctionName,
								exception == null? "": exception.getMessage(), 
								getStackTrace(exception));
	}
	
	private static String getStackTrace(Exception exception)
	{
		if(exception == null)
			return "";
		
		StringBuilder sb = new StringBuilder();
		StackTraceElement[] elements = exception.getStackTrace();
		for(int i = elements.length-1 ; i>=0 ; i--)
		{
			sb.append(elements[i].toString()).append("\n");
		}
		return sb.toString();
	}
	
}
